#include "List.h"

LTNode* LTInit()
{
    LTNode* phead = (LTNode*)malloc(sizeof(LTNode));
    if (NULL == phead)
    {
        perror("LTInit malloc fail");
        return NULL;
    }

    phead->a = 0;
    phead->prev = phead;
    phead->next = phead;
    return phead;
}

void LTDestroy(LTNode* phead)
{
    assert(phead);

    LTNode* cur = phead->next; 
    while (cur != phead)
    {
        LTNode* tmp = cur->next;
        free(cur);
        cur = tmp;
    }
}

void LTPrint(LTNode* phead)
{
    assert(phead);

    LTNode* cur = phead->next;
    while (cur != phead)
    {
        printf("%d ", cur->a);
        cur = cur->next;
    }
    printf("\n");
}

bool LTEmpty(LTNode* phead)
{
    assert(phead);

    return phead->next == phead;
}

void LTPushBack(LTNode* phead, LTDataType x)
{
    assert(phead);

    LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
    if (NULL == newnode)
    {
        perror("LTPushBack malloc fail");
        return;
    }

    newnode->a = x;
    newnode->next = phead;
    newnode->prev = phead->prev;
    phead->prev->next = newnode;
    phead->prev = newnode;
}

void LTPopBack(LTNode* phead)
{
    assert(phead);
    assert(!LTEmpty(phead));

    LTNode* tmp = phead->prev;
    phead->prev->prev->next = phead;
    phead->prev = phead->prev->prev;
    free(tmp);
    tmp = NULL;
}

void LTPushFront(LTNode* phead, LTDataType x)
{
    assert(phead);

    LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
    if (NULL == newnode)
    {
        perror("LTPushFront malloc fail");
        return;
    }

    newnode->a = x;
    newnode->prev = phead;
    newnode->next = phead->next;
    phead->next->prev = newnode;
    phead->next = newnode;
}

void LTPopFront(LTNode* phead)
{
    assert(phead);
    assert(!LTEmpty(phead));

    LTNode* tmp = phead->next;
    phead->next->next->prev = phead;
    phead->next = phead->next->next;
    free(tmp);
    tmp = NULL;
}

void LTInsert(LTNode* pos, LTDataType x)
{
    assert(pos);

    LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
    if (NULL == newnode)
    {
        perror("LTInsert malloc fail");
        return;
    }

    newnode->a = x;
    newnode->next = pos->next;
    newnode->prev = pos;
    pos->next->prev = newnode;
    pos->next = newnode;
}

void LTErase(LTNode* pos)
{
    assert(pos);
    
    LTNode* tmp = pos->next;
    pos->next->next->prev = pos;
    pos->next = pos->next->next;
    free(tmp);
    tmp = NULL;
}

LTNode* LTFind(LTNode* phead, LTDataType x)
{
    assert(phead);

    LTNode* cur = phead->next;
    while(cur != phead)
    {
        if (x == cur->a)
        {
            return cur;
        }
        cur = cur->next;
    }
    return NULL;
}